#include <iostream>
#include <sstream>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <Math.h>
#include "Map.hpp"
#include "cDAT.h"

#define INEXISTANT_RESSOURCE -1





Map::Map(): monde(1), niveau(1), nbMur(0), infosMapViewed(false) {}
Map::Map(string mapName){loadMap(mapName);
}

void Map::loadNextMap()
{
    if(niveau < 15)
    {
        stringstream concatenation;
        concatenation << "level"<<monde<<"."<<niveau<<".dat";
        string level = concatenation.str();
        currentLevel=level;
        loadMap(level);
        niveau++;
    }
    else
    {
        monde++;
        niveau=1;
        stringstream concatenation;
        concatenation << "level"<<monde<<"."<<niveau<<".dat";
        string level = concatenation.str();
        currentLevel=level;
        loadMap(level);
    }
}

void Map::loadMap(string mapNameFile)
{
    cDAT read_test;
    char* buffer;
    read_test.Read(mapNameFile);


    buffer = read_test.GetFile("map.txt");
    if(buffer == NULL)
    {
        cout << "Erreur ouverture de la map " << mapNameFile << endl;
        //exit(INEXISTANT_RESSOURCE);
    }
    else
    {
        int i=0;
        string bufint;

        mapName=mapNameFile;

        map.clear();

        while (buffer[i] != '\r') { bufint+=buffer[i];i++; } i++;
        typeMap = atoi(bufint.c_str()); bufint="";i++;
        while (buffer[i] != '\r') { bufint+=buffer[i];i++; } i++;
        infosMap=bufint; i++;bufint="";
        while (buffer[i] != '\r') { bufint+=buffer[i];i++; } i++;
        width = atoi(bufint.c_str()); bufint="";
        while (buffer[i] != '\r') { bufint+=buffer[i];i++; } i++;
        height = atoi(bufint.c_str()); bufint="";i++;


        vector<vector<int> > tab_damier(height, vector<int>(width, 0) );
        map=tab_damier;

        int taille=0;
        int hauteur=0;

        /*cout << width << endl;
        cout << height << endl;*/

        while(hauteur < height)
        {
            while(taille <= width){
                    int test;
                    bufint = buffer[i];
                    test = atoi(bufint.c_str());
                    map[hauteur][taille]=test;
                    //if(test == 1 ) nbMur++;
                    i++;
                    taille++;

            }
            hauteur++;taille=0;i++;
        }
        //cout << "Loading Map \"" << mapNameFile.substr(0, mapNameFile.find('.')+2) << "\" Done !" << endl;
    }
}
int Map::getValue(int x, int y)
{
    int x_cased = floor((float)x / (float)SIZEBLOCK);
    int y_cased = floor((float)y / (float)SIZEBLOCK);

    if(x_cased <= width && y_cased <= height)
        return map[y_cased][x_cased];
    else
        return -1;

}

void Map::afficher(sf::RenderWindow& window)
{
    cDAT read_test;
    char* buffer;
    read_test.Read(mapName);


    buffer = read_test.GetFile("Sol1.png");
    sf::Texture textureSol1;if (!textureSol1.loadFromMemory(buffer, read_test.GetFileSize("Sol1.png"))) exit(INEXISTANT_RESSOURCE);

    buffer = read_test.GetFile("Sol2.png");
    sf::Texture textureSol2;if (!textureSol2.loadFromMemory(buffer, read_test.GetFileSize("Sol2.png"))) exit(INEXISTANT_RESSOURCE);

    buffer = read_test.GetFile("mur.png");
    sf::Texture textureMur;if (!textureMur.loadFromMemory(buffer, read_test.GetFileSize("mur.png"))) exit(INEXISTANT_RESSOURCE);

    buffer = read_test.GetFile("sortie.png");
    sf::Texture textureSortie;
    sf::Image image;
    if (!image.loadFromMemory(buffer, read_test.GetFileSize("sortie.png"))) exit(INEXISTANT_RESSOURCE);

    image.createMaskFromColor(sf::Color(34,177,76),0);
    textureSortie.loadFromImage(image);
    texture.setSmooth(false);


    int pair=0;
    bool fin=false;

    for(int i=0;i<height;i++)
    {
        if(i == height-1) fin=true;
        for(int j=0;j<width;j++)
        {
            sprite.setPosition(j*SIZEBLOCK, i*SIZEBLOCK);
            switch(map[i][j])
            {
                case 0:
                    if(pair % 2 == 0)
                    {
                        sprite.setTexture(textureSol1);
                        window.draw(sprite);
                        pair++;
                    }
                    else
                    {
                        sprite.setTexture(textureSol2);
                        window.draw(sprite); pair=0;
                    }
                    break;
                case 1:
                    sprite.setTexture(textureMur);
                    window.draw(sprite);
                    if(!fin)
                    {
                        if(pair % 2 == 0) pair++;else pair=0;
                    }
                    else fin=false;
                    break;
                case 2:
                    if(pair % 2 == 0)
                    {
                        sprite.setTexture(textureSol1);
                        window.draw(sprite);
                        pair++;
                    }
                    else
                    {
                        sprite.setTexture(textureSol2);
                        window.draw(sprite); pair=0;
                    }
                    sprite.setTexture(textureSortie);
                    window.draw(sprite);
                    break;
                default:
                    break;
            }

        }
        if(width >= 20){
        if(pair % 2 == 0) pair++;
        else pair=0;
        }
    }


}


int Map::getWidth(){return width;}
int Map::getHeight(){return height;}
string Map::getMapName(){return mapName;}
std::string Map::getInfosMap(){return infosMap;}
bool Map::getInfosMapViewed(){return infosMapViewed;}
void Map::setInfosMapViewed(bool value){infosMapViewed=value;}
int Map::getNbMur(){return nbMur;}
string Map::getCurrentLevel(){return currentLevel;}
sf::Vertex* Map::getVertex(int i){return &wall[i];}
std::vector<sf::Vector2f >& Map::getVertor2fWall(){return vector2f;}
Map::~Map()
{
    map.clear();
}
